package com.wan37.logic.handler;

/**
 * @author : luoyong
 * @date : 2020-05-28 09:47
 **/

import com.google.protobuf.Message;
import com.wan37.logic.component.LogicWorkerHandlerCenter;
import com.wan37.logic.global.HandlerManager;
import com.wan37.logic.global.reference.SpringContextHolder;
import com.wan37.logic.service.cache.SceneServiceCache;
import com.wan37.protobuf.analysis.ParseMap;
import com.wan37.protobuf.message.internal.Internal;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * LogicServer的handler.
 * 负责处理来自LogicServer的消息.
 *
 * @author ly
 */
public final class LogicServerHandler extends SimpleChannelInboundHandler<Message> {

    private static final Logger logger = LoggerFactory.getLogger(LogicServerHandler.class);

    /**
     * 逻辑消息处理中心
     */
    private LogicWorkerHandlerCenter logicWorkerHandlerCenter;

    /**
     * gate连接的ctx
     */
    private static ChannelHandlerContext gateConnCtx;
    private SceneServiceCache sceneServiceCache;


    public LogicServerHandler(LogicWorkerHandlerCenter logicWorkerHandlerCenter) {
        this.logicWorkerHandlerCenter = logicWorkerHandlerCenter;
        this.sceneServiceCache = SpringContextHolder.getBean("sceneServiceCache");
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Message msg) throws Exception {
        /**
         * LogicServer收到了GateServer发来的消息.
         */

        Internal.GTransfer gt = (Internal.GTransfer) msg;
        //获得ptoNum
        int ptoNum = gt.getPtoNum();
        //获得消息对象
        Message message = ParseMap.getMessage(ptoNum, gt.getMsg().toByteArray());

        //判断消息类型
        MsgHandler msgHandler = null;
        logger.info("[LogicServer] 收到来自 [GateServer] 的 {} 消息.", message.getClass().getSimpleName());
        msgHandler = HandlerManager.getMsgHandler(ptoNum, gt.getUserId(), gt.getNetId(),
                message, getGateConnCtx());

        //将消息分发给LogicCenter中的Worker线程进行处理
        logger.debug("sceneId: {}, msgHandler: {}", gt.getSceneId(), msgHandler);
        logicWorkerHandlerCenter.distributeWork(gt.getSceneId(), msgHandler);
    }


    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

        cause.printStackTrace();
    }


    public static ChannelHandlerContext getGateConnCtx() {
        return gateConnCtx;
    }

    public static void setGateConnCtx(ChannelHandlerContext gateConnCtx) {
        LogicServerHandler.gateConnCtx = gateConnCtx;
    }


}
